package net.kesumu.yushabu;

import java.net.URI;
import java.net.URLEncoder;
import java.util.Locale;

import org.json.JSONException;
import org.json.JSONObject;

import net.kesumu.general.android.EasyStorage.EasyStorage;
import net.kesumu.general.android.view.BackgroundUtil;
import net.kesumu.general.android.view.CustomStatusBar;
import net.kesumu.general.debug.Debug;
import net.kesumu.yushabu.storage.FriendDbOperator;
import net.kesumu.yushabu.utils.JSONUtil;
import net.kesumu.yushabu.utils.WsConfig;
import net.kesumu.yushabuserver.entity.FriendRequest;
import net.kesumu.yushabuserver.entity.User;

import com.codebutler.android_websockets.WebSocketClient;
import com.umeng.message.PushAgent;

import net.kesumu.yushabu.R;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.transition.Visibility;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This activity is used to view userInfo and modify userInfo.
 * @author Z 2015-01-21
 *
 */
public class FriendActivity extends Activity {
    
    public final static String TYPE_FRIEND = "type_friend",
                               TYPE_OTHERS = "type_others",
                               TYPE_FRIEND_REQUEST = "type_friend_request";
    
    private EasyStorage mEasyStorage;
    
    boolean photoBackgroundSet = false;
    
    ImageView mPhotoView;
    TextView mNameView;
    TextView mIdView;
    TextView mGenderView;
    TextView mAreaView;
    TextView mSignatureView;
    
    Button mStartChatBtn;


    String mUserPhotoPath;
    String mUserName;
    String mUserId;
    String mUserGender;
    String mUserArea;
    String mUserSignature;
    String mUserYuYuChatId;
    
    String type;
    
    String mMyId;
    
    MenuItem deleteFriendMenu;
    
    // Hold a reference to the current animator,
    // so that it can be canceled mid-way.
    private Animator mCurrentAnimator;
    
    // The system "short" animation time duration, in milliseconds. This
    // duration is ideal for subtle animations or animations that occur
    // very frequently.
    private int mShortAnimationDuration;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_friend);
        getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); 
        getActionBar().setCustomView(R.layout.actionbar);
        ((TextView)findViewById(R.id.actionbar_title)).setText(getString(R.string.title_activity_friend));
        //Custom the status bar
        CustomStatusBar customStatusBar = new CustomStatusBar(this);
        customStatusBar.setStatusBarColor(findViewById(R.id.statusBarBackground), getResources().getColor(R.color.main));

        
        
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
        
        mEasyStorage = new EasyStorage(this, getString(R.string.preference_file_key));
        mMyId = mEasyStorage.getString("mMyId");
     
        Intent receiveIntent = getIntent();
        mUserId = receiveIntent.getStringExtra("userId");
        type = receiveIntent.getStringExtra("type");
        mUserPhotoPath = receiveIntent.getStringExtra("userPhotoPath");

        startUpClient();
        
        PushAgent.getInstance(this).onAppStart();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mPhotoView = (ImageView) findViewById(R.id.image_photo_friend);
        mNameView = (TextView) findViewById(R.id.text_name_friend);
        mIdView = (TextView) findViewById(R.id.text_id_friend);
        mGenderView = (TextView) findViewById(R.id.text_gender_friend);
        mAreaView = (TextView) findViewById(R.id.text_area_friend);
        mSignatureView = (TextView) findViewById(R.id.text_signature_friend);
         
        
        mStartChatBtn = (Button) findViewById(R.id.btn_startChat);
        
        
        //Judge the type of this FriendActivity
        if(type != null && type.equalsIgnoreCase(TYPE_OTHERS)) {
            //hide the actionbar menu
            ((TextView)findViewById(R.id.actionbar_title)).setText(getString(R.string.title_activity_userInfo));
            
            findViewById(R.id.btn_deleteFriend).setVisibility(View.GONE);
            findViewById(R.id.btn_startChat).setVisibility(View.GONE);
            findViewById(R.id.btn_refuse).setVisibility(View.GONE);
            findViewById(R.id.btn_accept).setVisibility(View.GONE);
        }else if(type != null && type.equalsIgnoreCase(TYPE_FRIEND_REQUEST)) {
            //hide the actionbar menu
            ((TextView)findViewById(R.id.actionbar_title)).setText(getString(R.string.title_activity_friendRequestDesination));
            
            findViewById(R.id.btn_deleteFriend).setVisibility(View.GONE);
            findViewById(R.id.btn_startChat).setVisibility(View.GONE);
            findViewById(R.id.btn_addFriend).setVisibility(View.GONE);
        }else if(type != null && type.equalsIgnoreCase(TYPE_FRIEND)){
            findViewById(R.id.btn_addFriend).setVisibility(View.GONE);
            findViewById(R.id.btn_refuse).setVisibility(View.GONE);
            findViewById(R.id.btn_accept).setVisibility(View.GONE);
            
            /*//Update the friend photo
            FriendDbOperator friendDbOperator = new FriendDbOperator(getApplicationContext());
            User selectedFriend = friendDbOperator.select(mUserId);
            String friendPhotoPath =  selectedFriend.getPhotoPath();
            if(friendPhotoPath != null && !friendPhotoPath.equalsIgnoreCase("")) {
                String mMyPhotoName = friendPhotoPath.substring(0, friendPhotoPath.indexOf("."));
                String mMyPhotoExtention = friendPhotoPath.substring(friendPhotoPath.indexOf(".")+1);
                Bitmap photo_friend = mEasyStorage.getImageBitmap(mMyPhotoName, mMyPhotoExtention);
                mPhotoView.setImageBitmap(photo_friend);
                final ImageView expandedImageView = (ImageView) findViewById(
                        R.id.image_photo_friend_extended);
                expandedImageView.setImageBitmap(photo_friend);
            }*/
        }
        
        if(mUserPhotoPath != null && !mUserPhotoPath.equalsIgnoreCase("")) {
            String userPhotoName = mUserPhotoPath.substring(0, mUserPhotoPath.indexOf("."));
            String userPhotoExtention = mUserPhotoPath.substring(mUserPhotoPath.indexOf(".")+1);
            Bitmap photo_user = mEasyStorage.getImageBitmap(userPhotoName, userPhotoExtention);
            if(photo_user!=null) {
                mPhotoView.setImageBitmap(photo_user);
                final ImageView expandedImageView = (ImageView) findViewById(
                        R.id.image_photo_friend_extended);
                expandedImageView.setImageBitmap(photo_user);
            }
        }
        
        if(!photoBackgroundSet) {
            Bitmap photo_friend = ((BitmapDrawable)(mPhotoView.getDrawable())).getBitmap();
            View background_photo_friend = findViewById(R.id.background_photo_friend);
            if(photo_friend!=null) {
                background_photo_friend.setBackgroundColor(BackgroundUtil.getAverageColor(photo_friend));
            }
            photoBackgroundSet = true;
        }
        
        
        
        mPhotoView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                
                zoomImageFromThumb(mPhotoView, R.drawable.no_profile);
            }
        });

        // Retrieve and cache the system's default "short" animation time.
        mShortAnimationDuration = getResources().getInteger(
                android.R.integer.config_shortAnimTime);
    }
    


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.friend, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        /*int id = item.getItemId();
        if (id == R.id.action_deleteFriend) {
            return true;
        }*/
        return super.onOptionsItemSelected(item);
    }
    
    public void startChat(View clickedView) {
        Intent messagingActivity = new Intent(FriendActivity.this,YushabuMessagingActivity.class);
        messagingActivity.putExtra("type", MessagingActivity.TYPE_SINGLE_CHAT);
        messagingActivity.putExtra("state", MessagingActivity.STATE_NOT_IN_ROOM);
//        messagingActivity.putExtra("myId", mMyId);
        messagingActivity.putExtra("yushabuSessionId", 0);
        messagingActivity.putExtra("friendId", mUserId);
        messagingActivity.putExtra("friendName", mUserName);
        startActivity(messagingActivity);
//        Intent yushabuMessagingActivity = new Intent(FriendActivity.this, YushabuMessagingActivity.class);
//        startActivity(yushabuMessagingActivity);
    }
    public void addFriend(View clickedView) {
        Intent friendRequestActivity = new Intent(FriendActivity.this,FriendRequestActivity.class);
//        friendRequestActivity.putExtra("myId", ""+mMyId);
        friendRequestActivity.putExtra("friendId", mUserId);
        startActivity(friendRequestActivity);
    }
    public void deleteFriend(View clickedView) {
        
    }
    
    public void acceptFriendRequest(View clickedView) {
        sendRequest(jsonUtil.getAcceptFriendRequestJSON(
                mUserId, mMyId));
    }
    
    public void refuseFriendRequest(View clickedView) {
        sendRequest(jsonUtil.getRefuseFriendRequestJSON(
                mUserId, mMyId));
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_friend,
                    container, false);
            return rootView;
        }
    }
    
    
    public void friendInfoGet() {
        sendRequest(jsonUtil.getUserInfoGetJSON(mUserId));
    }
    
    private void zoomImageFromThumb(final View thumbView, int imageResId) {
        // If there's an animation in progress, cancel it
        // immediately and proceed with this one.
        if (mCurrentAnimator != null) {
            mCurrentAnimator.cancel();
        }

        // Load the high-resolution "zoomed-in" image.
        final ImageView expandedImageView = (ImageView) findViewById(
                R.id.image_photo_friend_extended);
//        expandedImageView.setImageResource(imageResId);

        // Calculate the starting and ending bounds for the zoomed-in image.
        // This step involves lots of math. Yay, math.
        final Rect startBounds = new Rect();
        final Rect finalBounds = new Rect();
        final Point globalOffset = new Point();

        // The start bounds are the global visible rectangle of the thumbnail,
        // and the final bounds are the global visible rectangle of the container
        // view. Also set the container view's offset as the origin for the
        // bounds, since that's the origin for the positioning animation
        // properties (X, Y).
        thumbView.getGlobalVisibleRect(startBounds);
        findViewById(R.id.container)
                .getGlobalVisibleRect(finalBounds, globalOffset);
        startBounds.offset(-globalOffset.x, -globalOffset.y);
        finalBounds.offset(-globalOffset.x, -globalOffset.y);

        // Adjust the start bounds to be the same aspect ratio as the final
        // bounds using the "center crop" technique. This prevents undesirable
        // stretching during the animation. Also calculate the start scaling
        // factor (the end scaling factor is always 1.0).
        float startScale;
        if ((float) finalBounds.width() / finalBounds.height()
                > (float) startBounds.width() / startBounds.height()) {
            // Extend start bounds horizontally
            startScale = (float) startBounds.height() / finalBounds.height();
            float startWidth = startScale * finalBounds.width();
            float deltaWidth = (startWidth - startBounds.width()) / 2;
            startBounds.left -= deltaWidth;
            startBounds.right += deltaWidth;
        } else {
            // Extend start bounds vertically
            startScale = (float) startBounds.width() / finalBounds.width();
            float startHeight = startScale * finalBounds.height();
            float deltaHeight = (startHeight - startBounds.height()) / 2;
            startBounds.top -= deltaHeight;
            startBounds.bottom += deltaHeight;
        }

        // Hide the thumbnail and show the zoomed-in view. When the animation
        // begins, it will position the zoomed-in view in the place of the
        // thumbnail.
        thumbView.setAlpha(0f);
        expandedImageView.setVisibility(View.VISIBLE);

        // Set the pivot point for SCALE_X and SCALE_Y transformations
        // to the top-left corner of the zoomed-in view (the default
        // is the center of the view).
        expandedImageView.setPivotX(0f);
        expandedImageView.setPivotY(0f);

        // Construct and run the parallel animation of the four translation and
        // scale properties (X, Y, SCALE_X, and SCALE_Y).
        AnimatorSet set = new AnimatorSet();
        set
                .play(ObjectAnimator.ofFloat(expandedImageView, View.X,
                        startBounds.left, finalBounds.left))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
                        startBounds.top, finalBounds.top))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
                startScale, 1f)).with(ObjectAnimator.ofFloat(expandedImageView,
                        View.SCALE_Y, startScale, 1f));
        set.setDuration(mShortAnimationDuration);
        set.setInterpolator(new DecelerateInterpolator());
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mCurrentAnimator = null;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mCurrentAnimator = null;
            }
        });
        set.start();
        mCurrentAnimator = set;

        // Upon clicking the zoomed-in image, it should zoom back down
        // to the original bounds and show the thumbnail instead of
        // the expanded image.
        final float startScaleFinal = startScale;
        expandedImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mCurrentAnimator != null) {
                    mCurrentAnimator.cancel();
                }

                // Animate the four positioning/sizing properties in parallel,
                // back to their original values.
                AnimatorSet set = new AnimatorSet();
                set.play(ObjectAnimator
                            .ofFloat(expandedImageView, View.X, startBounds.left))
                            .with(ObjectAnimator
                                    .ofFloat(expandedImageView, 
                                            View.Y,startBounds.top))
                            .with(ObjectAnimator
                                    .ofFloat(expandedImageView, 
                                            View.SCALE_X, startScaleFinal))
                            .with(ObjectAnimator
                                    .ofFloat(expandedImageView, 
                                            View.SCALE_Y, startScaleFinal));
                set.setDuration(mShortAnimationDuration);
                set.setInterpolator(new DecelerateInterpolator());
                set.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        thumbView.setAlpha(1f);
                        expandedImageView.setVisibility(View.GONE);
                        mCurrentAnimator = null;
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                        thumbView.setAlpha(1f);
                        expandedImageView.setVisibility(View.GONE);
                        mCurrentAnimator = null;
                    }
                });
                set.start();
                mCurrentAnimator = set;
            }
        });
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
         
        if(client != null & client.isConnected()){
            client.disconnect();
        }
    }
    
    /**
     * Connection with the server
     */
    private WebSocketClient client;
    private JSONUtil jsonUtil;
    void startUpClient() {
        if(client != null && client.isConnected()) {
            return;
        }
        jsonUtil = new JSONUtil(getApplicationContext());
        client = new WebSocketClient(URI.create(WsConfig.URL_WEBSOCKET
                + URLEncoder.encode(WsConfig.SESSION_TAG_DEFAULT)), new WebSocketClient.Listener() {
            public void onConnect() {
                friendInfoGet();
            }
            public void onMessage(String message) {
                parseMessage(message);
            }
            public void onMessage(byte[] data) {
                // Message will be in JSON format
                parseMessage(JSONUtil.bytesToHex(data));
            }
            public void onDisconnect(int code, String reason) {
                String message = String.format(Locale.US,
                        "Disconnected! Code: %d Reason: %s", code, reason);
                showToast(message);
            }
            public void onError(Exception error) {
                showToast("Error! : " + error);
            }
        }, null);
        client.connect();
    }

    //remove the null judge for immediately send a message after connection setup
    private void sendRequest(String message) {
        client.send(message);
    }
    
    private void parseMessage(final String msg) {
 
        try {
            JSONObject jObj = new JSONObject(msg);
 
            // JSON node 'flag'
            String flag = jObj.getString("flag");

            if (flag.equalsIgnoreCase(JSONUtil.FLAG_USERINFO_GET)) {
                String result = jObj.getString("result");
                showToast(result);

                if(result.equalsIgnoreCase("success")) {
                    
                    mUserName = jObj.getString("userName");
                    mUserGender = jObj.getString("userGender");
                    mUserArea = jObj.getString("userArea");
                    mUserSignature = jObj.getString("userSignature");
                    mUserYuYuChatId = jObj.getString("yuyuChatId");

                    
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            findViewById(R.id.waiting).setVisibility(View.GONE);
                            
                           
                            mNameView.setText(mUserName);
                            mIdView.setText(mUserYuYuChatId);
                            mSignatureView.setText(mUserSignature);
                            mGenderView.setText(mUserGender);
                            mAreaView.setText(mUserArea);
                            
                       }
                    });
                }

                
            } else if (flag.equalsIgnoreCase(JSONUtil.FLAG_USERINFO_MODIFY)) {
                String result = jObj.getString("result");
                showToast(result);
                
                Intent backToMain = new Intent(this, MainActivity.class);
                startActivity(backToMain);
                finish();
                
            }else if (flag.equals(JSONUtil.FLAG_FRIEND_REQUEST_ACCEPT)) {
                String result = jObj.getString("result");
                showToast(result);
                
                if(result != null && result.equalsIgnoreCase("success")) {
                    Intent intent = new Intent(MainActivity.BROADCAST_TYPE_FRIEND_LIST);
                    sendBroadcast(intent);
                    finish();
                }
            }else if(flag.equals(JSONUtil.FLAG_FRIEND_REQUEST_REFUSE)) {
                String result = jObj.getString("result");
                showToast(result);
                if(result != null && result.equalsIgnoreCase("success")) {
                    finish();
                }
            }
 
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    
    private void showToast(final String message) {
        runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(getApplicationContext(), message,
                        Toast.LENGTH_SHORT).show();
            }
        });
 
    }

}
